{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    " ### 简介\n",
    "前面已经介绍过了一些模型，它们各有各的优缺点：  \n",
    "\n",
    "（1）比如SVM中，虽然它的最大化间隔能带来不错的泛化能力，但如果某些支持向量恰好是异常点，那么它的决策边界可能会错的很离谱；  \n",
    "\n",
    "（2）对于决策树，虽然它的非线性拟合能力很强，但如果放纵树的生长，它甚至会为了个别噪声点创建琐碎的规则；    \n",
    "\n",
    "（3）而对于logtic回归模型，它往往不会被个别噪声点影响，但它的模型结构简单，对于复杂的非线性可分数据又难以拟合；  \n",
    "\n",
    "......    \n",
    "\n",
    "\n",
    "那么，如果能将多个模型组合，对其取长补短，那么我们就有可能得到一个更加强大的模型，这便是集成学习的初衷，而它们的组合条件，可以简单归结为：**好而不同** "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 好而不同的解释\n",
    "\n",
    "（1）首先，单个模型的效果要尽可能的“好”，这个理解起来很自然（虽然理论证明只要比随机的好一点就行，但大部分情况还是选择好的模型）；  \n",
    "\n",
    "（2）其次，就是模型与模型之间尽可能的不同，这很好理解，如果大家都是一样的，那对相同的输入，都给出相同的预测，这就没有意义了，它们没法规避同样的“坑”"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 训练方式:boosting & bagging\n",
    "根据个体模型的生成方式，大体可以分为两类：  \n",
    "\n",
    "（1）一类是boosting算法，它以串行的方式生成基模型，每个模型的训练需要参考前一阶段的结果，比如对上一轮错分的样本调整权重、或对上一轮预测的残差再做训练等，这方面的代表模型有adaboost以及gbdt(梯度提升树)，简单说来如下：    \n",
    "\n",
    "![avatar](./source/10_boosting简介.png)   \n",
    "\n",
    "\n",
    "\n",
    "（2）另一类是bagging算法，它以并行的方式生成模型，通过投票来做决定，比较有代表的就是随机森林，简单说来如下：  \n",
    "![avatar](./source/10_bagging简介.png)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### \"不同\"的方式\n",
    "前面讲了组合的条件是：**好而不同**，以及它们的生成方式：**串行和并行**，接下来说说如何做到与众不同？这可以从3个方面的来源：数据输入、数据输出、模型自身以及其生成方式做讨论：       \n",
    "\n",
    "\n",
    "来源\\训练方式 | 串行 | 并行 |\n",
    ":-: | :-: | :-: | \n",
    "输入 | 样本权重扰动 | 样本抽样扰动、样本特征扰动 | \n",
    "输出 | 残差、梯度| 输出表示扰动 | \n",
    "模型 | 超参扰动| 超参扰动 | \n",
    "\n",
    "接下来做一下解释：  \n",
    "\n",
    "（1）**样本权重扰动**：adaboost的方式，它根据上一轮的训练结果，对预测正确的样本降低权重，对训练错误的样本升高权重；  \n",
    "\n",
    "（2）**样本抽样扰动**：bagging的处理方法，对每个模型的训练数据进行有放回的抽样(又叫做bootstrap抽样)；  \n",
    "\n",
    "（3）**样本特征扰动**：随机森林的方式，它不仅对每个模型做boostrap抽样，而且对当前处理的特征属性还要做抽样，以尽可能与其他模型不同；  \n",
    "\n",
    "（4）**梯度**：这是梯度提升树的训练方式，每一轮的训练目标是损失函数关于上一轮目标的梯度；  \n",
    "\n",
    "（5）**残差**：这是梯度提升树的一个特例，它的损失函数为平方损失的情况，每一轮的训练目标是真实目标与上一轮预测结果之间的差值；  \n",
    "\n",
    "（6）**输出表示扰动**：这可以理解为对训练数据随机加入噪声；  \n",
    "\n",
    "（7）**超参扰动**：对同类型的模型，也可以通过调节其超参数，使得其训练出来的模型不同，比如对决策树，可以限制其不同的深度、最少叶子节点数等..."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 如何组合结果？\n",
    "\n",
    "对预测数据，每个模型都会给出自己的预测结果，那么该如何组合这些结果呢？简单来说主要有如下的三种方式：    \n",
    "\n",
    "（1）公平的方式：即每个模型的话语权相等，对回归任务直接求平均，对分类任务，做投票，选择投票数最多的类别；   \n",
    "\n",
    "（2）加权的方式：根据模型在训练阶段的不同表现，会赋予其不同的权重，最后对其做加权，求结果；   \n",
    "\n",
    "（3）stacking的方式：这是一种比较高级的组合方式，它训练另外一个模型去做组合，即将基模型的输出作为该模型的输入，原始训练数据的目标作为该模型的输出目标"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "###  小结一下\n",
    "\n",
    "这一节没有代码没有公式，主要对集成学习的相关概念做一个梳理，其核心主要是如下两点：   \n",
    "\n",
    "（1）如何生成好而不同的模型：“准确性”和“多样性”这两者其实是冲突的，很多时候需要在这两者之间做一个权衡；   \n",
    "\n",
    "（2）如何做组合：组合的方式不同，会直接对输出结果造成影响，一般来说，基模型的性能相差不大时可以采用公平的方式做组合，如果性能差异较大，可以采用加权的方式做组合"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
